{
TÍTULO: Práctica de EDI
SUBTÍTULO: Practica 1
AUTOR: Sergio Morlán Reborido 	LOGIN: infsmr03
GRUPO: E.I
FECHA: 08/05/09
}
UNIT listadinamica;
INTERFACE
CONST NULO = NIL;
TYPE
	tNumeroTelefono = string;
	tOperadorTelefono = string;
	tInfo = RECORD
		NumeroTelefono: tNumeroTelefono;
		OperadorTelefono: tOperadorTelefono;
	END;
	tPos = ^tnodo;
	tnodo = RECORD
		Info : tInfo;
		sig : tPos;
	END;
	tLista = tPos;
	
PROCEDURE ListaVacia(VAR L:tLista);
FUNCTION esListaVacia (L:tLista): boolean;
FUNCTION Primero(L:tLista):tPos;
FUNCTION Ultimo (L:tLista):tPos;
FUNCTION Siguiente (L:tLista; p:tPos):tPos;
FUNCTION Anterior (L:tLista; p:tPos):tPos;
FUNCTION InsertarOrdenado (VAR L:tLista; num:tNumeroTelefono;oper:tOperadorTelefono):boolean;
PROCEDURE Borrar (VAR L:tLista; p:tPos);
PROCEDURE ObtenerDato(L:tLista;p:tPos;VAR num:tNumeroTelefono;VAR oper:tOperadorTelefono);
PROCEDURE ActualizaDato (VAR L:tLista; p:tPos; oper:tOperadorTelefono);
FUNCTION Buscar (L:tlista; num:tNumeroTelefono):tPos;


IMPLEMENTATION

{Tarea:  Crea un nuevo nodo
Entrada: num: numero telefono
			oper: operador telefonico
         nuevoNodo: Elemento de la lista
Salida: Devuelve true si ha ejecutado con éxito y un Nuevo elemento para insertar en una lista
}
FUNCTION crearNodo(num:tNumeroTelefono; oper:tOperadorTelefono; VAR nuevoNodo:tPos): boolean;
BEGIN
   new(nuevoNodo);
   IF (nuevoNodo <>NULO) THEN BEGIN
   	nuevoNodo^.Info.NumeroTelefono:= num;
		nuevoNodo^.Info.OperadorTelefono:= oper;
   	crearNodo:=TRUE;
   END
	ELSE
   	crearNodo:=FALSE;
end;

{Tarea:Crea una lista vacia
Entrada: La lista
Salida:Devuelve la lista creada
}
PROCEDURE ListaVacia(VAR L:tlista);
BEGIN
   L:=NIL
END;

{Tarea:Comprueba si la lista esta vacia
Entrada:Recibe la lista
Salida:Devuelve un true si esta vacia y un false si no lo esta
}
FUNCTION esListaVacia(L:tlista): boolean;
BEGIN
   esListaVacia:=(L=NIL)
END;

{Tarea:Devuelve la posicion del primer elemento de la lista
Entrada:La lista
Salida:Si la lista esta vacia devuelve un nulo
}
FUNCTION Primero(L:tLista):tPos;
BEGIN
   IF NOT esListaVacia(L) THEN Primero:=L
   ELSE Primero:=NULO
END;

{Tarea:Devuelve la posicion del ultimo elemento de la lista
Entrada:Recibe la lista
Salida:Si la lista esta vacia devuelve un nulo
}
FUNCTION Ultimo(L:tLista):tPos;
BEGIN
   IF L<>NIL THEN 
      WHILE L^.sig<>NIL DO L:=L^.sig;
   Ultimo:=L
END;

{Tarea:Devuelve la posicion del siguiente elemento a la posicion indicada
Entrada:Recibe la lista y la posicion de la que hay que devolver el siguiente elemento
Salida:Nulo si la posicion recibida no tiene siguiente
PreCD:La posicion debe ser valida 
}
FUNCTION Siguiente(L:tLista; p:tPos):tPos;
BEGIN
   Siguiente:=p^.sig
END;

{Tarea:Devuelve la posicion del anterior elemento a la posicion indicada
Entrada:Recibe la lista y la posicion de la que hay que devolver el anterior elemento
Salida:Nulo si la posicion recibida no tiene anterior
PreCD:La posicion debe ser valida 
}
FUNCTION Anterior(L:tLista; p:tPos):tPos;
VAR
        q:tPos;
BEGIN
   IF p=L THEN Anterior:=NULO
   ELSE BEGIN
      q:=L;
      WHILE q^.sig<>p DO q:=q^.sig;
      Anterior:=q;
   END
END;

{Tarea:Insertar en la lista los numeros de telefono y el operador de forma ordenada por el numero de telefono
Entrada:Recibe la lista, el numero de telefono y el operador a insertar
Salida:La lista con el dato insertado, y un booleano para saber si el dato fue insertado
PreCD:No debe existir ya un elemento en la lista con ese numero de telefono
}
FUNCTION InsertarOrdenado(VAR L:tLista; num:tNumeroTelefono;oper:tOperadorTelefono):boolean;
VAR
	q,nuevoNodo:tpos;
BEGIN
	IF crearNodo(num,oper,nuevoNodo) THEN BEGIN
      IF esListaVacia(L) THEN BEGIN
			nuevoNodo^.sig:=NULO;
			L:=nuevoNodo;
      END
      ELSE BEGIN
      	IF (L^.Info.NumeroTelefono>num) THEN BEGIN
         	nuevoNodo^.sig:=L;
         	L:=nuevoNodo;
         END
         ELSE BEGIN
         	q:=L;
            WHILE(q^.sig<>NULO) AND (q^.sig^.Info.NumeroTelefono<num) DO
         	   q:=q^.sig;
            nuevoNodo^.sig:=q^.sig;
            q^.sig:=nuevoNodo;
         END;
   		InsertarOrdenado:=TRUE;
      END;
   END
	ELSE InsertarOrdenado:=FALSE
END;


{Tarea:Borra de la lista el elemento que esta en la posicion indicada,reorganizando la lista y liberando esa posicion
Entrada:Recibe la lista y la posicion del elemento a borrar
Salida:La lista con el dato borrado
PreCD:La posicion debe ser valida
}
PROCEDURE Borrar(VAR L:tLista; p:tPos);
VAR
   q:tPos;
BEGIN
   IF p=L THEN L:=L^.sig
   ELSE BEGIN
      q:=Anterior(L,p);
      q^.sig:=p^.sig;{al elemento que tenía que apuntar como siguiente ya no está, es el borrado, y por lo tanto tiene que apuntar al siguiente del siguiente(al que apuntaba el que fue borrado}
   END;
   dispose (p);
END;

{Tarea:Obtener toda la informacion de la posicion indicada
Entrada:Recibe la lista,la posicion,el numero de telefono y el operador
Salida:El numero de telefono yel operador de esa posicion
PreCD:La posicion tiene que ser válida
}
PROCEDURE ObtenerDato(L:tLista;p:tPos;VAR num:tNumeroTelefono;VAR oper:tOperadorTelefono);
BEGIN
   num:=p^.Info.NumeroTelefono;
   oper:=p^.Info.OperadorTelefono;
END;

{Tarea:Actualiza los datos en la posicion indicada
Entrada:Recibe la lista, la posicion y el operador de telefeno
Salida:La lista con el operador actualizado en la posicion correspondiente
PreCD:La posicion tiene que ser valida
}
PROCEDURE ActualizaDato(VAR L:tLista; p:tPos; oper:tOperadorTelefono);
BEGIN
   p^.Info.OperadorTelefono:=oper;
END;

{Tarea:Busca en la lista la posicion del elemento cuyo numero telefono coincida con el recibido
Entrada:Recibe la lista y el numero de telefono a buscar en ella
Salida:Nulo si el elemento no se encontro
}
FUNCTION Buscar(L:tlista; num:tNumeroTelefono):tPos;
BEGIN
   IF L<>NULO THEN
   BEGIN
      WHILE (L<>NULO) AND (L^.Info.NumeroTelefono<>num) DO
         L:=L^.sig;
   END;
   Buscar:=L;
END;

BEGIN
END.

